package com.xexun.gpstracker.util;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.Manifest;
import android.app.Activity;
import android.content.*;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.util.Log;

import com.xexun.gpstracker.channel.R;
import com.xexun.gpstracker.common.Constants;
import com.xexun.gpstracker.fix.grant.PermissionsManager;
import com.xexun.gpstracker.fix.grant.PermissionsResultAction;
import com.xexun.gpstracker.inter.CommDialogListener;
import com.xexun.gpstracker.pojo.Device;
import com.xexun.gpstracker.vo.GroupEntity;
import com.xexun.gpstracker.vo.Session;

/**
 * Created by lc on 2015/9/29 0029.
 * 通讯录工具类
 */
public class ContactsUtil {
    private Context context;
    private ExecutorService executor;

    private ContactsUtil(Context context) {
        this.context = context;
    }

    private static ContactsUtil instance = null;

    private static synchronized ContactsUtil getInstance(Context context) {
        if (instance == null) {
            synchronized (ContactsUtil.class) {
                if (instance == null) {
                    instance = new ContactsUtil(context);
                }
            }
        }
        return instance;
    }

    /**
     * 检查和添加联系人群组
     *
     * @return 已创建或已存在的群组
     */
    public synchronized GroupEntity checkContactGroup(String groupName) {
        GroupEntity gp = getContactGroup(groupName);
        if (gp != null) {
            return gp;
        } else {
            ContentValues values = new ContentValues();
            values.put(ContactsContract.Groups.TITLE, groupName);
            context.getContentResolver().insert(ContactsContract.Groups.CONTENT_URI, values);
            return getContactGroup(groupName);
        }
    }

    /**
     * 获取联系人群组
     *
     * @param groupName
     * @return
     */
    private synchronized GroupEntity getContactGroup(String groupName) {
        GroupEntity ge = null;
        Cursor cursor = null;
        try {
            cursor = context.getContentResolver().query(ContactsContract.Groups.CONTENT_URI, null, null, null, null);
            while (cursor != null && cursor.moveToNext()) {
                String gn = cursor.getString(cursor.getColumnIndex(ContactsContract.Groups.TITLE)); // 组名
                if (CommUtil.isNotBlank(gn) && gn.equals(groupName)) {
                    int groupId = cursor.getInt(cursor.getColumnIndex(ContactsContract.Groups._ID)); // 组id
                    ge = new GroupEntity();
                    ge.setGroupId(groupId);
                    ge.setGroupName(groupName);
                    break;
                }
            }
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return ge;
    }

    private synchronized void clearContactsByGroup(String groupName) {
        GroupEntity group = getContactGroup(groupName);
        deleteContactsByGroup(group);
    }

    private synchronized void deleteContactsByGroup(GroupEntity group) {
        if (group == null) {
            return;
        }
        Cursor groupTypeCur = null;
        try {
            ContentResolver resolver = context.getContentResolver();
            //查找在指定群组下所有人员的raw_contact_id
            groupTypeCur = resolver.query(ContactsContract.Data.CONTENT_URI, new String[]{ContactsContract.Data.RAW_CONTACT_ID},
                    ContactsContract.Data.DATA1 + "=? and " + ContactsContract.Data.MIMETYPE + "=?",
                    new String[]{String.valueOf(group.getGroupId()), ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE}, null);
            if (groupTypeCur == null || groupTypeCur.isAfterLast()) {
                return;
            }
            while (groupTypeCur.moveToNext()) {
                int id = groupTypeCur.getInt(0);
                resolver.delete(ContactsContract.RawContacts.CONTENT_URI, ContactsContract.Data._ID + "=?", new String[]{String.valueOf(id)});
                resolver.delete(ContactsContract.Data.CONTENT_URI, ContactsContract.Data.RAW_CONTACT_ID + "=?", new String[]{String.valueOf(id)});
            }
        } catch (Exception e) {
            Log.e(ContactsUtil.class.getName(), "出错", e);
        } finally {
            if (groupTypeCur != null) {
                groupTypeCur.close();
            }
        }
    }

    /**
     * 删除联系人
     *
     * @param group 群组
     * @param phone 电话号码
     */
    public synchronized void deleteContact(GroupEntity group, String phone) {
        Cursor cursor = null;
        Cursor groupTypeCur = null;
        try {
            ContentResolver resolver = context.getContentResolver();
            //查找在指定群组下所有人员的raw_contact_id
            groupTypeCur = resolver.query(ContactsContract.Data.CONTENT_URI, new String[]{ContactsContract.Data.RAW_CONTACT_ID},
                    ContactsContract.Data.DATA1 + "=? and " + ContactsContract.Data.MIMETYPE + "=?",
                    new String[]{String.valueOf(group.getGroupId()), ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE}, null);
            if (groupTypeCur == null || groupTypeCur.isAfterLast()) {
                return;
            }
            //遍历，找到对应号码所属记录，并删掉
            String selection = ContactsContract.CommonDataKinds.Phone.NUMBER + "=? and " + ContactsContract.Data.RAW_CONTACT_ID + "=?";
            while (groupTypeCur.moveToNext()) {
                int rawContactId = groupTypeCur.getInt(0);
                cursor = resolver.query(ContactsContract.Data.CONTENT_URI, new String[]{ContactsContract.Data.RAW_CONTACT_ID}, selection, new String[]{phone, String.valueOf(rawContactId)}, null);
                if (cursor == null) {
                    continue;
                }
                if (cursor.moveToNext()) {
                    int id = cursor.getInt(0);
                    //根据id删除data中的相应数据
                    resolver.delete(ContactsContract.RawContacts.CONTENT_URI, ContactsContract.Data._ID + "=?", new String[]{String.valueOf(id)});
                    resolver.delete(ContactsContract.Data.CONTENT_URI, ContactsContract.Data.RAW_CONTACT_ID + "=?", new String[]{String.valueOf(id)});
                }
                cursor.close();
            }
        } catch (Exception e) {
            Log.e(ContactsUtil.class.getName(), "出错", e);
        } finally {
            if (cursor != null) {
                cursor.close();
            }
            if (groupTypeCur != null) {
                groupTypeCur.close();
            }
        }
    }

    /**
     * 添加联系人
     *
     * @param group     联系人所属群组
     * @param monitorId
     * @param name      联系人姓名
     * @param phone     联系人电话
     */
    private synchronized void addContact(GroupEntity group, long monitorId, String name, String phone) {
        /**
         * 首先向RawContacts.CONTENT_URI执行一个空值插入，目的是获取系统返回的rawContactId
         *
         * 这是后面插入data表的数据，只有执行空值插入，才能使插入的联系人在通讯录里可见
         */

        ContentValues values = new ContentValues();
        //首先向RawContacts.CONTENT_URI执行一个空值插入，目的是获取系统返回的rawContactId
        ContentResolver resolver = context.getContentResolver();
        Uri rawContactUri = resolver.insert(ContactsContract.RawContacts.CONTENT_URI, values);
        long rawContactId = ContentUris.parseId(rawContactUri);

        //往data表写入姓名数据
        values.clear();
        values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
        values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
        values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, name);
        resolver.insert(ContactsContract.Data.CONTENT_URI, values);

        //往data表写入电话数据
        values.clear();
        values.put(ContactsContract.Contacts.Data.RAW_CONTACT_ID, rawContactId);
        values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
        values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone);
        values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
        resolver.insert(ContactsContract.Data.CONTENT_URI, values);

        //往data表写入IM信息
//        values.clear();
//        values.put(ContactsContract.Contacts.Data.RAW_CONTACT_ID, rawContactId);
//        values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE);
//        values.put(ContactsContract.CommonDataKinds.Im.CUSTOM_PROTOCOL, Constants.CONTACT_GROUP_NAME);
//        values.put(ContactsContract.CommonDataKinds.Im.PROTOCOL, ContactsContract.CommonDataKinds.Im.PROTOCOL_CUSTOM);
//        values.put(ContactsContract.CommonDataKinds.Im.DATA, monitorId);
//        resolver.insert(ContactsContract.Data.CONTENT_URI, values);

        //往data表写入群组数据
        values.clear();
        values.put(ContactsContract.Contacts.Data.RAW_CONTACT_ID, rawContactId);
        values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE);
        values.put(ContactsContract.CommonDataKinds.GroupMembership.DATA1, group.getGroupId());
        resolver.insert(ContactsContract.Data.CONTENT_URI, values);
    }

    /**
     * 新建/更新 监护人和监护对象
     */
    private synchronized void syncContacts() {
        if (null == executor) {
            executor = Executors.newSingleThreadExecutor();
        }
        executor.submit(new ContactsUpdateTask());
    }

    private class ContactsUpdateTask implements Runnable {
        @Override
        public void run() {
            ContactsUtil.getInstance(context);
            clearContactsByGroup(Constants.CONTACT_GROUP_NAME);
            GroupEntity group = checkContactGroup(Constants.CONTACT_GROUP_NAME);
            List<Device> monitors = Session.getInstance().getMonitors();
            for (Device device : monitors) {
                addContact(group, device.getMonitorId(), device.getName(), device.getPhone());
            }

//            List<Keeper> userList = Session.getInstance().getUserList();
//            for (Keeper keeper : userList) {
//                util.addContact(group, keeper.getNickName(), keeper.getCellPhone());
//            }
//
//            List<TermFriend> friends = Session.getInstance().getFriendList();
//            for (TermFriend fd : friends) {
//                util.addContact(group, fd.getName(), fd.getCellPhone());
//            }
        }
    }

    public static void requestSyncContact(Activity activity) {
        SharedPreferences sp = Utils.getPreferences(activity);
        final String[] permissions = new String[]{Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS};
        boolean isShowContactPermission = sp.getBoolean(Constants.SHOWN_CONTACT_PERMISSION, false);
        if (!isShowContactPermission) {
            CommDialogListener<Activity> commDialogListener = new CommDialogListener<Activity>(activity) {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(getActivity(),
                            permissions,
                            new PermissionsResultAction() {
                                @Override
                                public void onGranted() {
                                    ContactsUtil.getInstance(getActivity()).syncContacts();
                                }

                                @Override
                                public void onDenied(String permission) {
                                    CommUtil.showMsgShort(getActivity().getString(R.string.permission_refuse_contact_note));
                                }
                            });
                }
            };
            Utils.showNotifyDialog(activity, R.string.note, R.string.msg_show_contact_permission, R.string.known, 0, commDialogListener, null, 0, null);
            sp.edit().putBoolean(Constants.SHOWN_CONTACT_PERMISSION, true).apply();
        } else if (PermissionsManager.getInstance().hasAllPermissions(activity, permissions)) {
            ContactsUtil.getInstance(activity).syncContacts();
        }
    }
}
